home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Icon 8.1 / msm-1 / icont.sit / tmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-19  |  13.1 KB  |  548 lines  |  [TEXT/MPS ]

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "::h:gsupport.h"
  6. #include "tproto.h"
  7.  
  8. /*
  9.  * Prototypes.
  10.  */
  11.  
  12. hidden    novalue    execute    Params((char *ofile,char *efile,char * *args));
  13. hidden    novalue    report Params((char *s));
  14. hidden    novalue    rmfiles Params((char **p));
  15. hidden    novalue    usage Params((noargs));
  16.  
  17. /*
  18.  * The following code is operating-system dependent [@tmain.01].  Include
  19.  *  files and such.
  20.  */
  21.  
  22. #if PORT
  23. Deliberate syntax error
  24. #endif                    /* PORT */
  25.  
  26. #if AMIGA
  27. #include <libraries/dosextens.h>
  28. #endif                    /* AMIGA */
  29.  
  30. #if ARM || MSDOS || MVS || UNIX || VM || VMS
  31. /* nothing is needed */
  32. #endif                    /* ARM || ... */
  33.  
  34. #if ATARI_ST
  35. char *patharg;
  36. #endif                    /* ATARI_ST */
  37.  
  38. #if MACINTOSH
  39. #if MPW
  40. #include <fcntl.h>    /* MPW3 - for unlink() */
  41. #include <CursorCtl.h>
  42. void SortOptions();
  43. #endif                    /* MPW */
  44. #endif                    /* MACINTOSH */
  45.  
  46. #if OS2
  47. #include <process.h>
  48. #endif                    /* OS2 */
  49. /*
  50.  * End of operating-system specific code.
  51.  */
  52.  
  53. #if IntBits == 16
  54. #ifdef strlen
  55. #undef strlen                /* pre-defined in some contexts */
  56. #endif                    /* strlen */
  57. #endif                    /* Intbits == 16 */
  58.  
  59. /*
  60.  *  Define global variables.
  61.  */
  62.  
  63. #define Global
  64. #define Init(v) = v
  65. #include "globals.h"
  66.  
  67. char *ofile = NULL;            /* linker output file name */
  68.  
  69. char patchpath[MaxPath+18] = "%PatchStringHere->";
  70.  
  71. /*
  72.  * The following code is operating-system dependent [@tmain.02].  Definition
  73.  *  of refpath.
  74.  */
  75.  
  76. #if PORT
  77.    /* something is needed */
  78. Deliberate Syntax Error
  79. #endif                    /* PORT */
  80.  
  81. #if UNIX || AMIGA || ATARI_ST || MACINTOSH || MSDOS || MVS || OS2 || VM
  82. char *refpath = RefPath;
  83. #endif                    /* UNIX ... */
  84.  
  85. #if VMS
  86. char *refpath = "ICON_BIN:";
  87. #endif                    /* VMS */
  88.  
  89. /*
  90.  * End of operating-system specific code.
  91.  */
  92.  
  93. char *iconxloc;
  94.  
  95. /*
  96.  * getopt() variables
  97.  */
  98. extern int optindex;        /* index into parent argv vector */
  99. extern int optopt;        /* character checked for validity */
  100. extern char *optarg;        /* argument associated with option */
  101.  
  102. /*
  103.  *  main program
  104.  */
  105. novalue main(argc,argv)
  106. int argc;
  107. char **argv;
  108.    {
  109.    int nolink = 0;            /* suppress linking? */
  110.    int errors = 0;            /* translator and linker errors */
  111.    char **tfiles, **tptr;        /* list of files to translate */
  112.    char **lfiles, **lptr;        /* list of files to link */
  113.    char **rfiles, **rptr;        /* list of files to remove */
  114.    char *efile = NULL;            /* stderr file */
  115.    char buf[MaxFileName];        /* file name construction buffer */
  116.    int c, n;
  117.    struct fileparts *fp;
  118.  
  119. #if AMIGA
  120. #if AZTEC_C
  121.    struct Process *FindTask();
  122.    struct Process *Process = FindTask(0L);
  123.    ULONG stacksize = *((ULONG *)Process->pr_ReturnAddr);
  124.  
  125.    if (stacksize < ICONTMINSTACK) {
  126.       fprintf(stderr,"Icont needs \"stack %d\" to run\n",ICONTMINSTACK);
  127.       exit(-1);
  128.       }
  129. #endif                    /* AZTEC_C */
  130. #endif                    /* AMIGA */
  131.  
  132.  
  133. #if MACINTOSH
  134. #if MPW
  135.    InitCursorCtl(NULL);
  136.    SortOptions(argv);
  137. #endif                    /* MPW */
  138. #endif                    /* MACINTOSH */
  139.  
  140.    iconxloc = (char *)alloc((unsigned)strlen(refpath) + 6);
  141.    strcpy(iconxloc, refpath);
  142.    strcat(iconxloc, "iconx");
  143.  
  144.    if (strlen(patchpath)>18)
  145.       iconxloc = patchpath+18;
  146.  
  147.    /*
  148.     * Process options.
  149.     */
  150.    while ((c = getopt(argc,argv,Options)) != EOF)
  151.       switch (c) {
  152.          case 'C':            /* Ignore: compiler only */
  153.             break;
  154.  
  155. #ifdef Xver
  156. xver(tmain.1)
  157. #endif                    /* Xver */
  158.  
  159.          case 'L':            /* -L: enable linker debugging */
  160.  
  161. #ifdef DeBugLinker
  162.             Dflag = 1;
  163. #endif                    /* DeBugLinker */
  164.  
  165.             break;
  166.  
  167.          case 'S':            /* -S */
  168.             fprintf(stderr, "Warning, -S option is obsolete\n");
  169.             break;
  170.          case 'c':            /* -c: compile only (no linking) */
  171.             nolink = 1;
  172.             break;
  173.          case 'e':            /* -e file: redirect stderr */
  174.             efile = optarg;
  175.             break;
  176.          case 'f':            /* Ignore: compiler only */
  177.             break;
  178.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  179.             m4pre = 1;
  180.             break;
  181.          case 'n':            /* Ignore: compiler only */
  182.             break;
  183.          case 'o':            /* -o file: name output file */
  184.             ofile = optarg;
  185.             break;
  186.  
  187.          case 'p':            /* -p path: iconx path [ATARI] */
  188. #if ATARI_ST
  189.             patharg = optarg;
  190. #endif                    /* ATARI_ST */
  191.             break;
  192.  
  193.          case 'r':            /* Ignore: compiler only */
  194.             break;
  195.          case 's':            /* -s: suppress informative messages */
  196.             silent = 1;
  197.             break;
  198.          case 't':            /* -t: turn on procedure tracing */
  199.             trace = -1;
  200.             break;
  201.          case 'u':            /* -u: warn about undeclared ids */
  202.             uwarn = 1;
  203.             break;
  204.          case 'v':            /* Ignore: compiler only */
  205.             break;
  206.          default:
  207.          case 'x':            /* -x illegal until after file list */
  208.             usage();
  209.          }
  210.  
  211.    /*
  212.     * Allocate space for lists of file names.
  213.     */
  214.    n = argc - optindex + 1;
  215.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  216.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  217.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  218.  
  219.    /*
  220.     * Scan file name arguments.
  221.     */
  222.    while (optindex < argc)  {
  223.       if (strcmp(argv[optindex],"-x") == 0)    /* stop at -x */
  224.          break;
  225.       else if (strcmp(argv[optindex],"-") == 0) {
  226.  
  227. #if ARM
  228.     /* Different file naming, so we need a different strategy... */
  229.     *tptr++ = "-";
  230.     /* Use makename(), pretending we had an input file named "Stdin" */
  231.     makename(buf,TargetDir,"Stdin",U1Suffix);
  232.     *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  233.     makename(buf,TargetDir,"Stdin",U2Suffix);
  234.     *rptr++ = salloc(buf);        /* also remove .u2 */
  235.  
  236. #else                    /* ARM */
  237.  
  238.          *tptr++ = "-";                /* "-" means standard input */
  239.          *lptr++ = *rptr++ = "stdin.u1";
  240.          *rptr++ = "stdin.u2";
  241. #endif                    /* ARM */
  242.  
  243.          }
  244.       else {
  245.          fp = fparse(argv[optindex]);        /* parse file name */
  246.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  247.             makename(buf,SourceDir,argv[optindex], SourceSuffix);
  248. #if VMS
  249.         strcat(buf, fp->version);
  250. #endif                    /* VMS */
  251.             *tptr++ = salloc(buf);        /* translate the .icn file */
  252.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  253.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  254.             makename(buf,TargetDir,argv[optindex],U2Suffix);
  255.             *rptr++ = salloc(buf);        /* also remove .u2 */
  256.             }
  257.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  258.                || smatch(fp->ext,USuffix)) {
  259.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  260.             *lptr++ = salloc(buf);
  261.             }
  262.          else
  263.             quitf("bad argument %s",argv[optindex]);
  264.          }
  265.       optindex++;
  266.       }
  267.  
  268.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  269.    if (lptr == lfiles)
  270.       usage();                /* error -- no files named */
  271.  
  272.    /*
  273.     * Round hash table sizes to next power of two, and set masks for hashing.
  274.     */
  275.    chsize = round2(chsize);  cmask = chsize - 1;
  276.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  277.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  278.    ihsize = round2(ihsize);  imask = ihsize - 1;
  279.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  280.  
  281.    /*
  282.     * Translate .icn files to make .u1 and .u2 files.
  283.     */
  284.    if (tptr > tfiles) {
  285.       if (!silent)
  286.          report("Translating");
  287.       errors = trans(tfiles);
  288.       if (errors > 0)            /* exit if errors seen */
  289.          exit(ErrorExit);
  290.       }
  291.  
  292.    /*
  293.     * Link .u1 and .u2 files to make an executable.
  294.     */
  295.    if (nolink) {            /* exit if no linking wanted */
  296.  
  297. #if MACINTOSH
  298. #if MPW
  299.       /*
  300.        *  Set type of translator output ucode (.u) files
  301.        *  to 'TEXT', so they can be easily viewed by editors.
  302.        */
  303.       {
  304.       char **p;
  305.       void setfile();
  306.       for (p = rfiles; *p; ++p)
  307.          setfile(*p,'TEXT','icon');
  308.       }
  309. #endif                    /* MPW */
  310. #endif                    /* MACINTOSH */
  311.  
  312.       exit(NormalExit);
  313.       }
  314.  
  315.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  316.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  317.    } else {                /* add extension in necessary */
  318.       fp = fparse(ofile);
  319.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  320.          ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
  321.    }
  322.  
  323.    if (!silent)
  324.       report("Linking");
  325.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  326.  
  327.    /*
  328.     * Finish by removing intermediate files.
  329.     *  Execute the linked program if so requested and if there were no errors.
  330.     */
  331.  
  332. #if MACINTOSH
  333. #if MPW
  334.    /* Set file type to TEXT so it will be executable as a script. */
  335.    setfile(ofile,'TEXT','icon');
  336. #endif                    /* MPW */
  337. #endif                    /* MACINTOSH */
  338.  
  339.    rmfiles(rfiles);            /* remove intermediate files */
  340.    if (errors > 0) {            /* exit if linker errors seen */
  341.       unlink(ofile);
  342.       exit(ErrorExit);
  343.       }
  344.  
  345. #if !(MACINTOSH && MPW)
  346.    if (optindex < argc)  {
  347.       if (!silent)
  348.          report("Executing");
  349.       execute (ofile, efile, argv+optindex+1);
  350.       }
  351. #endif                    /* !(MACINTOSH && MPW) */
  352.  
  353.    exit(NormalExit);
  354.    }
  355.  
  356. /*
  357.  * execute - execute iconx to run the icon program
  358.  */
  359. static novalue execute(ofile,efile,args)
  360. char *ofile, *efile, **args;
  361.    {
  362.  
  363. #if !(MACINTOSH && MPW)
  364.    int n;
  365.    char **argv, **p;
  366.  
  367.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  368.       ;
  369.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  370.  
  371.    *p++ = iconxloc;            /* set iconx pathname */
  372.    if (efile != NULL) {            /* if -e given, copy it */
  373.       *p++ = "-e";
  374.       *p++ = efile;
  375.       }
  376.    *p++ = ofile;            /* pass icode file name */
  377.  
  378. #if AMIGA && LATTICE
  379.    *p = *args;
  380.    while (*p++) {
  381.       *p = *args;
  382.       args++;
  383.    }
  384. #else                    /* AMIGA && LATTICE */
  385.    while (*p++ = *args++)        /* copy args into argument vector */
  386.       ;
  387. #endif                    /* AMIGA && LATTICE */
  388.  
  389.    *p = NULL;
  390.  
  391. /*
  392.  * The following code is operating-system dependent [@tmain.03].  It calls
  393.  *  iconx on the way out.
  394.  */
  395.  
  396. #if PORT
  397.    /* something is needed */
  398. Deliberate Syntax Error
  399. #endif                    /* PORT */
  400.  
  401. #if AMIGA
  402. #if AZTEC_C
  403.       execvp(iconxloc,argv);
  404.       return;
  405. #endif                    /* AZTEC_C */
  406. #if LATTICE
  407.       {
  408.       struct ProcID procid;
  409.       if (forkv(iconxloc,argv,NULL,&procid) == 0) { 
  410.          wait(&procid);
  411.          return;
  412.          }
  413.       }
  414. #endif                    /* LATTICE */
  415. #endif                    /* AMIGA */
  416.  
  417. #if ARM
  418.    {
  419.       int i = 7 + strlen(iconxloc);
  420.       int j;
  421.       char *s;
  422.       char buffer[255];
  423.       extern int armquote(char *, char **);
  424.  
  425.       sprintf(buffer, "Chain:%s ", iconxloc);
  426.       for (p = argv + 1; *p; ++p)
  427.       {
  428.          j = armquote(*p, &s);
  429.  
  430.          if (j == -1 || i + j >= 255)
  431.          {
  432.             fprintf(stderr, "Cannot execute: command line too long");
  433.             fflush(stderr);
  434.             return;
  435.          }
  436.  
  437.          strcpy(buffer + i, s);
  438.          i += j;
  439.          buffer[i] = ' ';
  440.       }
  441.       buffer[i] = '\0';
  442.       system(buffer);
  443.    }
  444. #endif                    /* ARM */
  445.  
  446. #if ATARI_ST || MACINTOSH
  447.       fprintf(stderr,"-x not supported\n");
  448.       fflush(stderr);
  449. #endif                    /* ATARI_ST || ... */
  450.  
  451. #if MSDOS
  452. #if LATTICE || MICROSOFT || TURBO
  453.       execvp(iconxloc,argv);    /* execute with path search */
  454. #endif                    /* LATTICE || MICROSOFT || ... */
  455. #if MWC || INTEL_386 || ZTC_386 || HIGHC_386 || WATCOM
  456.       fprintf(stderr,"-x not supported\n");
  457.       fflush(stderr);
  458. #endif                    /* MWC || INTEL_386 || ... */
  459. #endif                    /* MSDOS */
  460.  
  461. #if MVS || VM
  462. #if SASC
  463.       exit(sysexec(iconxloc, argv));
  464. #endif                    /* SASC */
  465.       fprintf(stderr,"-x not supported\n");
  466.       fflush(stderr);
  467. #endif                                  /* MVS || VM */
  468.  
  469. #if OS2
  470.       execvp(iconxloc,argv);    /* execute with path search */
  471. #endif                    /* OS2 */
  472.  
  473. #if UNIX
  474.       /*
  475.        * If an ICONX environment variable is defined, use that.
  476.        *  If not, first try the predefined path, then search $PATH via execvp. 
  477.        */
  478.       if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  479.          execv(argv[0], argv);    /* exec file specified by $ICONX */
  480.          quitf("cannot execute $ICONX (%s)", argv[0]);
  481.          }
  482.  
  483. #ifdef HardWiredPaths
  484. #ifdef CRAY
  485.       argv[0] = "iconx";
  486.       execv(iconxloc, argv);
  487. #else                    /* CRAY */
  488.       argv[0] = iconxloc;        /* try predefined file */
  489.       execv(argv[0], argv);
  490. #endif                    /* CRAY */
  491. #endif                    /* HardWiredPaths */
  492.  
  493.       argv[0] = "iconx";
  494.       execvp(argv[0], argv);    /* if no iconxloc, search path for "iconx" */
  495.  
  496. #ifdef HardWiredPaths
  497.       quitf("cannot run %s", iconxloc);
  498. #else                    /* HardWiredPaths */
  499.       quitf("cannot find iconx", "");
  500. #endif                    /* HardWiredPaths */
  501. #endif                    /* UNIX */
  502.  
  503. #if VMS
  504.       execv(iconxloc,argv);
  505. #endif                    /* VMS */
  506.  
  507. /*
  508.  * End of operating-system specific code.
  509.  */
  510.  
  511.    quitf("could not run %s",iconxloc);
  512.  
  513. #else                    /* !(MACINTOSH && MPW) */
  514.    printf("-x not supported\n");
  515. #endif                    /* !(MACINZTOSH && MPW) */
  516.  
  517.    }
  518.  
  519. static novalue report(s)
  520. char *s;
  521.    {
  522.  
  523.    fprintf(stderr,"%s:\n",s);
  524.  
  525.    }
  526.  
  527. /*
  528.  * rmfiles - remove a list of files
  529.  */
  530.  
  531. static novalue rmfiles(p)
  532. char **p;
  533.    {
  534.    for (; *p; p++) {
  535.       unlink(*p);
  536.       }
  537.    }
  538.  
  539. /*
  540.  * Print an error message if called incorrectly.  The message depends
  541.  *  on the legal options for this system.
  542.  */
  543. static novalue usage()
  544.    {
  545.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, TUsage);
  546.    exit(ErrorExit);
  547.    }
  548.